import processor, re, string, inventorysupport

directions = []
directions.append( ("north", "n") )
directions.append( ("south", "s") )
directions.append( ("east", "e") )
directions.append( ("west", "w") )
directions.append( ("northeast", "ne") )
directions.append( ("southwest", "sw") )
directions.append( ("southeast", "se") )
directions.append( ("northwest", "nw") )
directions.append( ("up",) )
directions.append( ("down",) )
directionNames = [a[0] for a in directions]

processor.statusEntries.append("")

class Room(object):
    def __init__(self, name, desc):
        self.name = name
        self.desc = desc
        self.contents = [] #objects in the room
        self.posted = False #whether the description been shown
    def __str__(self):
        return self.name
    def acquire(self, object):
        if object not in processor.objects: processor.objects.append(object)
        if object.container: object.container.remove(object)
        self.contents.append(object)
        object.container = self.contents
    def setTwoWay(self, direction, room):
        if direction in directionNames:
            self.setOneWay(direction, room)
            room.setOneWay(invertDirection(direction), self);
        else:
            raise InvalidRoomError("The direction is invalid.")
    def setOneWay(self, direction, room):
        if direction in directionNames:
            self.__dict__[direction] = room
        else:
            raise InvalidRoomError("The direction is invalid.")
    def getDescription(self):
        self.posted = True
        s = self.name + "\n\n"
        s += self.desc + "\n"
        movableObjects = [a.nameAsUnknown() for a in self.contents if a.isMovable()]
        if len(movableObjects): s += "You see " + processor.smartJoin(movableObjects) + " here."
        return s
rooms = []

def getRoom(name):
    for room in rooms:
        if room.name == name:
            return room

def invertDirection(direction):
    if directionNames.index(direction) % 2:
        return directionNames[directionNames.index(direction)-1]
    else:
        return directionNames[directionNames.index(direction)+1]

processor.me.room = None

class InvalidRoomError(Exception):
    text = "You cannot go in that direction."
    def __init__(self, value = None):
        self.value = value or self.text
    def __str__(self): return self.value

def setRoom(self, room):
    if room:
        if self.room:
            for o in self.room.contents: processor.accessibleObjects.remove(o)
            self.room.posted = False
        self.room = room
        for o in self.room.contents: processor.accessibleObjects.append(o)
        processor.statusEntries[0] = str(room)
    else:
        raise InvalidRoomError()
processor.transplant(setRoom, processor.me)

def go(self, direction):
    if self.room and direction in directionNames:
        if direction in self.room.__dict__:
            self.setRoom(self.room.__dict__[direction])
        else:
            raise InvalidRoomError()
processor.transplant(go, processor.me)

class Hook(object):
    def hook(self, hooktype, command, ret):
        if not processor.me.room.posted and (hooktype == processor.PREPROCESS_CALL or hooktype == processor.STARTUP_CALL):
            return processor.me.room.getDescription()
processor.hooks.append(Hook())

class Direction(object):
    def process(self, command):
        try:
            valid = False
            for lst in directions:
                if re.match("^(" + string.join(lst, "|") + ")$", command):
                    processor.me.go(lst[0])
                    valid = True
            if not valid:
                return None
        except InvalidRoomError, e:
            return str(e)
        processor.me.room.posted = True
        return processor.me.room.getDescription()

processor.commands.append(Direction())



class Look(object):
    def process(self, command):
        if command == "look":
            processor.me.room.posted = True
            return processor.me.room.getDescription()

processor.commands.append(Look())
